package com.jy.api.controller.pay;

import com.alibaba.fastjson.JSON;
import com.jy.api.config.WebSocketUrlUtils;
import com.jy.api.dao.*;
import com.jy.api.domain.*;
import com.jy.api.enums.PayTypeEnum;
import com.jy.api.enums.RechargeEnum;
import com.jy.api.pay.result.PayResult;
import com.jy.api.payReq.ALLPayQrCodeResult;
import com.jy.api.payReq.AllPayJsPayResult;
import com.jy.api.payReq.HuiFuCallBackReq;
import com.jy.api.payReq.SaoBeiCallBackReq;
import com.jy.api.payRes.HuiFuBasicPayRes;
import com.jy.api.payRes.SuiXinFuCallBackRes;
import com.jy.api.service.*;
import com.jy.api.service.impl.*;
import com.jy.api.signUpReq.ScanCodeSignUpReq;
import com.jy.api.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by lihu on 2017/10/7.
 */
@Slf4j
@RestController
@RequestMapping(value = "v1/pay", produces = "application/json;charset=utf-8")
public class PayController {
    @Autowired
    PayService payService;
    @Autowired
    StoreDao storeDao;
    @Autowired
    PaymentService paymentService;
    @Autowired
    EmployeeDao employeeDao;
    @Autowired
    WebRechargeDao webRechargeDao;
    @Autowired
    WorkShiftDao workShiftDao;
    @Autowired
    WebRechargeService webRechargeService;
    @Autowired
    OrderService orderService;
    @Autowired
    StoreOrderService storeOrderService;
    @Autowired
    RedisService redisService;
    @Autowired
    private HuiFuServiceImpl huiFuService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private ProductService productService;
    @Autowired
    private HSServiceImpl hsService;
    @Autowired
    private StorePayDao storePayDao;
    @Autowired
    private JLServiceImpl jlService;
    @Autowired
    private SaoBeiServiceImpl saoBeiService;
    @Autowired
    private SuiXinFuServiceImpl suiXinFuService;
    @Autowired
    private ProductDao productDao;
    @Autowired
    private WebSocketUrlUtils urlUtils;
    @Resource
    private Environment environment;
    @Resource
    private RedisSyncLocker redisSyncLocker;

    /**
     * 支付回调地址
     *
     * @param xml
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "/callBack")
    public ResponseEntity callBack(@RequestBody String xml) {
        log.info("Received payment result notify, the content is:{}", xml);
        try {
            paymentService.handlePaymentNotify(xml);
            return ResponseEntity.ok("success");
        } catch (Exception e) {
            log.error("Fail to handle payment notify", e);
            return ResponseEntity.ok("fail");
        }
    }

    /**
     * 支付回调地址
     *
     * @param req
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "/saobei/callBack")
    public ResponseEntity saoBeiCallBack(@RequestBody String req) {
        log.info("Received payment result notify, the content is:{}", req);
        String s = "";
        try {
            SaoBeiCallBackReq callBackReq = JSON.parseObject(req, SaoBeiCallBackReq.class);
            s = callBackReq.getTerminal_trace();
            log.info("订单号{}, 操作{}, 操作内容{},参数{}", s, "扫呗集合支付回调", "开始", req);
            return ResponseEntity.ok(paymentService.saoBeiPaymentNotify(callBackReq));
        } catch (Exception e) {
            log.info("订单号{}, 操作{}, 操作内容{},参数{}", s, "扫呗集合支付回调", "error", e);
            return ResponseEntity.ok("fail");
        }
    }

    /**
     * 支付回调地址
     *
     * @param req
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "/huifu/callBack")
    public ResponseEntity huifuCallBack(@RequestBody String req) {
        log.info("Received payment result notify, the content is:{}", req);
        String s = "";
        try {
            HuiFuBasicPayRes res = JSON.parseObject(req, HuiFuBasicPayRes.class);
            HuiFuCallBackReq callBackReq = JSON.parseObject(res.getJsonData(), HuiFuCallBackReq.class);
            s = callBackReq.getMerOrdId();
            log.info("订单号{}, 操作{}, 操作内容{},参数{}", s, "汇付集合支付回调", "开始", req);
            return ResponseEntity.ok(paymentService.huifuPaymentNotify(callBackReq));
        } catch (Exception e) {
            log.info("订单号{}, 操作{}, 操作内容{},参数{}", s, "汇付集合支付回调", "error", e);
            return ResponseEntity.ok("fail");
        }
    }

    /**
     * 支付回调地址
     *
     * @param req
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "/suixinfu/callBack")
    public ResponseEntity suixinfuCallBack(@RequestBody String req) {
        log.info("Received payment result notify, the content is:{}", req);
        String s = "";
        try {
            SuiXinFuCallBackRes res = JSON.parseObject(req, SuiXinFuCallBackRes.class);
            s = res.getOrdNo();
            log.info("订单号{}, 操作{}, 操作内容{},参数{}", s, "随心付pc支付回调", "开始", req);
            paymentService.suixinfuPaymentNotify(res);
            return ResponseEntity.ok("{\"code\":\"success\",\"msg\":\"成功\"}");
        } catch (Exception e) {
            log.info("订单号{}, 操作{}, 操作内容{},参数{}", s, "随心付pc支付回调", "error", e);
            return ResponseEntity.ok("{\"code\":\"failed\",\"msg\":\"失败\"}");
        }
    }

    /**
     * 支付回调地址
     *
     * @param req
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "/lease/suixinfu/callBack")
    public ResponseEntity suixinfuLeaseCallBack(@RequestBody String req) {
        log.info("Received payment result notify, the content is:{}", req);
        String s = "";
        try {
            SuiXinFuCallBackRes res = JSON.parseObject(req, SuiXinFuCallBackRes.class);
            s = res.getOrdNo();
            log.info("订单号{}, 操作{}, 操作内容{},参数{}", s, "随心付pc支付回调", "开始", req);
            paymentService.suixinfuPaymentNotifyFrozen(res);
            return ResponseEntity.ok("{\"code\":\"success\",\"msg\":\"成功\"}");
        } catch (Exception e) {
            log.info("订单号{}, 操作{}, 操作内容{},参数{}", s, "随心付pc支付回调", "error", e);
            return ResponseEntity.ok("{\"code\":\"failed\",\"msg\":\"失败\"}");
        }
    }

    @PostMapping("/hs/stockCallBack")
    public ResponseEntity hsStockOrderCallBack(@RequestBody String xml) {
        log.info("Received payment result notify, the content is:{}", xml);
        try {
            paymentService.handleHsStockNotify(xml);
            return ResponseEntity.ok("success");
        } catch (Exception e) {
            log.error("Fail to handle payment notify", e);
            return ResponseEntity.ok("fail");
        }

    }

    @PostMapping("/sxf/stockCallBack")
    public ResponseEntity sxfStockOrderCallBack(@RequestBody String xml) {
        log.info("Received payment result notify, the content is:{}", xml);
        try {
            SuiXinFuCallBackRes res = JSON.parseObject(xml, SuiXinFuCallBackRes.class);
            paymentService.handleSxfStockNotify(res);
            return ResponseEntity.ok("success");
        } catch (Exception e) {
            log.error("Fail to handle payment notify", e);
            return ResponseEntity.ok("fail");
        }

    }

    /**
     * 用于店铺支付回调
     *
     * @param result
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "store/callBack")
    public ResponseEntity storeCallBack(@RequestBody String result) {
        log.info("storeCallBack is info result:{} ", result);
        PayResult payResult = XmlUtils.fromXML(result, PayResult.class);
        try {
            if (payResult.successCallBack()) {
                storeOrderService.handleStoreOrder(payResult);
            }
        } catch (Exception ex) {
            log.error("storeCallBack pay fail:{}", payResult);
        }
        return new ResponseEntity("isPaymentSuccess", HttpStatus.OK);
    }

    /**
     * 用于店铺充值回调回调
     *
     * @param result
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "recharge/callBack")
    public ResponseEntity rechargeCallBack(@RequestBody String result) {
        log.info("storeCallBack is info result:{} ", result);
        PayResult payResult = XmlUtils.fromXML(result, PayResult.class);
        try {
            if (payResult.successCallBack()) {
                webRechargeService.updateWebRecharge(payResult);
            }
        } catch (Exception ex) {
            log.error("storeCallBack pay fail:{}", payResult);
        }
        return new ResponseEntity("isPaymentSuccess", HttpStatus.OK);
    }

    /**
     * 用于二维码支付订单结果查询查询
     *
     * @param orderId
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/scan-code/query")
    public ResponseEntity payScanQuery(@RequestParam(name = "orderId") String orderId) {
        Order order = orderService.findOne(orderId);

        //如果订单状态已更改
        if (OrderStatus.FINISHED == order.getStatus() || OrderStatus.UNFINISHED == order.getStatus()) {
            return new ResponseEntity(HttpStatus.OK);
        } else if (OrderStatus.CANCELED == order.getStatus()) {
            return new ResponseEntity("支付失败！请核实！", HttpStatus.BAD_REQUEST);
        }else {
            return new ResponseEntity(HttpStatus.ACCEPTED);
        }
    }

    /**
     * 订单查询接口
     *
     * @param orderId
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/micropay/query")
    public ResponseEntity payCardQuery(@RequestParam(name = "orderId") String orderId) {
        // // TODO: 2018/8/28 订单查询接口可以通用，不需要区分刷卡支付还是扫码支付，甚至不需要区分在线支付和现金支付
        Order order = orderService.findOne(orderId);
        if (OrderStatus.FINISHED == order.getStatus() || OrderStatus.UNFINISHED == order.getStatus()) {
            // 支付成功
            return new ResponseEntity(HttpStatus.OK);
        } else if (OrderStatus.NOTSURE == order.getStatus()) {
            // 支付中
            return new ResponseEntity(HttpStatus.ACCEPTED);
        } else if (order.getStatus().equals(OrderStatus.FAIL)) {
            // 支付失败
            return new ResponseEntity("支付失败，请与顾客确认", HttpStatus.BAD_REQUEST);
        } else if (order.getStatus().equals(OrderStatus.INIT)) {
            return new ResponseEntity("支付失败，请重新支付！", HttpStatus.BAD_REQUEST);
        } else if (order.getStatus().equals(OrderStatus.CANCELED)) {
            return new ResponseEntity("支付失败，请重新支付！", HttpStatus.BAD_REQUEST);
        } else {
            return new ResponseEntity("支付结果未知，请稍后在订单列表中查看", HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 微信公众号支付初始化请求参数接口（？？？）
     *
     * @param orderId
     * @param request
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/web-pay")
    public ResponseEntity webPay(@RequestParam(name = "orderId") String orderId,
                                 @RequestParam(name = "openId") String openId,
                                 @RequestParam(name = "tableNo", defaultValue = "") String tableNo,
                                 @RequestParam(name = "phone", defaultValue = "") String phone,
                                 @RequestParam(name = "notes", defaultValue = "") String
                                         notes, @RequestParam(value = "mobile", defaultValue = "") String
                                         mobile, @RequestParam(value = "name", defaultValue = "") String name,
                                 HttpServletRequest request) throws Exception {
        Map<String, Object> orderData = new HashMap<>();
        orderData.put("notes", notes);
        orderData.put("tableNo", tableNo);
        orderService.patch(orderId, orderData);
        Order order = orderService.findOne(orderId);
        String s = UuidUtil.getUuid();
        String appendStr = s.substring(s.length() - 4);
        order.setPayOrderId(appendStr + order.getId());

        WorkShift workShift = workShiftDao.findByStoreIdAndClosed(order.getStoreId(), false);
        List<WorkShift> list = workShiftDao.findByStoreIdAndClosedOrderByAddTimeDesc(order.getStoreId(), false);
        if (list.isEmpty()) {
            return new ResponseEntity("收银台暂未开班，请联系收银台开班后，在进行点单", HttpStatus.BAD_REQUEST);
        }
        if (StringUtils.isNotBlank(mobile)) {
            Store store = storeDao.findOne(order.getStoreId());
            order.setCreatorName(name);
            order.setCreatorId(mobile);
            order.setMobileTag(workShift.getOperatorId());
            List<Employee> employee = employeeDao.findByStoreIdAndUsername(order.getStoreId(), mobile);
            double orderComission = 0;
            for (OrderItem item : order.getItems()) {
                if (employee.size() > 0) {
                    Product product = productDao.findOne(item.getProductId());
                    double itemComission = new BigDecimal(order.addEmpCommissionBeforePay(product, item.getQuantity(), product.getCommissions(), employee.get(0), item)).multiply(new BigDecimal(store.getGlobalRate())).doubleValue();
                    item.setCommission(itemComission);
                    orderComission += itemComission;
                }
            }
            order.setCommission(orderComission);
        }
        log.info("订单号{},员工手机号{},员工名字{}", order.getId(), mobile, name);
        orderService.saveOrder(order);
        StorePay storePay = storePayDao.findByStoreIdAndStartEnabled(order.getStoreId(), true);
        AllPayJsPayResult result = new AllPayJsPayResult();
        switch (storePay.getChannel()) {
            case HUI_SHANG:
                result = hsService.jsPay(storePay, orderId, openId);
                break;
            case JL:
                result = jlService.jlJsPay(storePay.getMchId(), openId, order);
                break;
            case SAO_BEI:
                result = saoBeiService.saoBeiJSPay(storePay, order, openId);
            case HUI_FU:
                result = huiFuService.huifuJsPay(storePay, orderId, openId);
            case SUI_XIN_FU:
                result = suiXinFuService.suixinfuJSPay(storePay, order, openId);
        }
        if (result.isSuccess()) {
            return new ResponseEntity(result.getPayInfo(), HttpStatus.OK);
        } else {
            return new ResponseEntity(result.getErrMsg(), HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 店铺收费
     *
     * @param type
     * @param request
     * @return
     */
    @Transactional
    @RequestMapping(method = RequestMethod.GET, value = "/web/scan-code")
    public ResponseEntity scanCode(@RequestParam(name = "storeId") String storeId,
                                   @RequestParam(name = "rechargeType") RechargeEnum rechargeEnum,
                                   @RequestParam(name = "type", defaultValue = "true") boolean type,
                                   HttpServletRequest request) {

        Store store = storeDao.findOne(storeId);
        if (store == null) {
            return new ResponseEntity("店铺信息不存在！", HttpStatus.BAD_REQUEST);
        }
        String checkResult = store.checkRechargeLevel(rechargeEnum);
        if (StringUtils.isNotBlank(checkResult)) {
            return new ResponseEntity(checkResult, HttpStatus.BAD_REQUEST);
        }

        //换算充值金额
        int amount = 0;
        switch (rechargeEnum) {
            case UPGRADE:
                amount = 200000;
                break;
            case THREE_LEVEL:
                amount = 320000;
                break;
            case SECOND_LEVEL:
                amount = 120000;
                break;
        }
        String payType = null;
        PaymentChannel channel = null;
        if (type) {
            payType = PayTypeEnum.PAY_ALIPAY_NATIVE.getCode();
            channel = PaymentChannel.ALIPAY;
        } else {
            payType = PayTypeEnum.PAY_WX_NATIVE.getCode();
            channel = PaymentChannel.WECHATPAY;
        }

        try {
            String uuId = UuidUtil.getUuid();
            PayResult scanCodeResult = payService.MyQRCode(IpUtils.getIpAddr(request),
                    payType, uuId, amount);
            if (StringUtils.equals(scanCodeResult.getStatus(), "0") &&
                    StringUtils.equals(scanCodeResult.getResultCode(), "0")) {
                WebRecharge webRecharge = new WebRecharge(uuId, storeId, channel, amount);
                webRechargeDao.save(webRecharge);
                Map map = new HashMap();
                map.put("url", scanCodeResult.getCodeImgUrl());
                map.put("id", webRecharge.getId());
                return new ResponseEntity(map, HttpStatus.OK);
            } else {
                log.error("scanCode  is error :{}", scanCodeResult);
                return new ResponseEntity(scanCodeResult.getErrMsg()
                        != null ? scanCodeResult.getErrMsg() : scanCodeResult.getMessage(), HttpStatus.BAD_REQUEST);
            }
        } catch (Exception ex) {
            log.error("scanCode  is error==> storeId:{}", storeId, ex);
            return new ResponseEntity("系统运行错误", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 店铺充值查询轮询接口
     *
     * @param id
     * @return
     */
    @Transactional
    @RequestMapping(method = RequestMethod.GET, value = "/scan-code/web-query")
    public ResponseEntity webScanQuery(@RequestParam(name = "id") String id) {
        try {
            WebRecharge webRecharge = webRechargeDao.findOne(id);
            if (webRecharge == null) {
                return new ResponseEntity("充值信息不存在！", HttpStatus.BAD_REQUEST);
            }
            if (webRecharge.getStatus() == PaymentStatus.SUCCESS) {
                return new ResponseEntity(HttpStatus.OK);
            } else {
                return new ResponseEntity(HttpStatus.ACCEPTED);
            }
        } catch (Exception ex) {
            log.error("payScanQuery  is error==> id{}", id, ex);
            return new ResponseEntity("支付失败！请切换支付方式！", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 扫码支付统一下单接口
     *
     * @param empId
     * @param
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/emp/work")
    public ResponseEntity empWork(@RequestParam("empId") String empId) throws Exception {
        Employee employee = employeeDao.findOne(empId);
        if (employee == null) {
            return ResponseEntity.badRequest().body("员工不存在，请刷新后重试");
        }
        if (!employee.isWork()) {
            return ResponseEntity.badRequest().body("该员工已下班，请重新选择！");
        }
        return ResponseEntity.ok("判断成功");
    }

    /**
     * 扫码支付统一下单接口
     *
     * @param
     * @param
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/jump/scan-code")
    public ResponseEntity jumpScanCode(@RequestParam("orderId") String orderId) {
        Order order = orderService.findOne(orderId);
        if (order == null) {
            return ResponseEntity.badRequest().body("订单异常，请重新点单");
        }
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("Location", redisService.get(order.getId() + "payUrl"));
        log.info("订单号{},跳转链接{}", order.getId(), redisService.get(order.getId() + "payUrl"));
        redisService.set(order.getId() + "noPay", orderId, 3*60*60);
        notifyScanCodeWs(order);
        return new ResponseEntity(map, HttpStatus.MOVED_PERMANENTLY);
    }

    /**
     * 扫码支付统一下单接口
     *
     * @param scanCodeSignUpReq
     * @param
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "/scan-code")
    public ResponseEntity getScanCode(@Valid @RequestBody ScanCodeSignUpReq scanCodeSignUpReq) throws Exception {
      return (ResponseEntity)  redisSyncLocker.StringKeyLock(scanCodeSignUpReq.getOrderId(), o -> {
            Order switchOrder = orderService.findOne(scanCodeSignUpReq.getOrderId());
            if (switchOrder == null) {
                return ResponseEntity.badRequest().body("订单不存在，请重新下单");
            }
            if (new Date().getTime() - switchOrder.getAddTime().getTime() > 10 * 60 * 1000){
                return ResponseEntity.badRequest().body("订单超时，请重新下单后进行支付");
            }
            String code = redisTemplate.opsForValue().get(switchOrder.getStoreId() + "switch");
            if (code != null && code.equals("TRUE")) {
                return ResponseEntity.badRequest().body("交班中，请等待交班完成后进行点单");
            }
            if (switchOrder.getType().equals(OrderType.SALES)) {
                List<String> strings = productService.judgeProductQty(switchOrder.getId());
                if (strings.size() > 0) {
                    return ResponseEntity.badRequest().body("订单中含有库存数量不足的商品，请移除后进行支付。");
                }
            }
            if (!switchOrder.getStatus().equals(OrderStatus.INIT) && !switchOrder.getStatus().equals(OrderStatus.CANCELED)) {
                log.warn("The status of order:{} is {}, micro pay is not allowed.", switchOrder.getId(), switchOrder.getStatus());
                return ResponseEntity.badRequest().body("订单当前状态不允许进行支付，请返回主页重新下单！");
            }

            WorkShift workShift = workShiftDao.findByStoreIdAndClosed(switchOrder.getStoreId(), false);
            List<WorkShift> list = workShiftDao.findByStoreIdAndClosedOrderByAddTimeDesc(switchOrder.getStoreId(), false);
            if (list.isEmpty()) {
                return new ResponseEntity("收银台暂未开班，请联系收银台开班后，在进行点单", HttpStatus.BAD_REQUEST);
            }
            Map<String, Object> orderData = new HashMap<>();
            orderData.put("notes", scanCodeSignUpReq.getNotes());
            orderData.put("tableNo", scanCodeSignUpReq.getTableNo());
            orderService.patch(scanCodeSignUpReq.getOrderId(), orderData);

            PayTypeEnum payType = scanCodeSignUpReq.isType() ? PayTypeEnum.PAY_ALIPAY_NATIVE : PayTypeEnum.PAY_WX_NATIVE;
            Order order = orderService.findOne(scanCodeSignUpReq.getOrderId());
            for (OrderItem item : order.getItems()) {
                Product product = productDao.findOne(item.getProductId());
                if (product != null) {
                    if (!product.checkSupplyTime()) {
                        return new ResponseEntity(product.getMsg(), HttpStatus.BAD_REQUEST);
                    }
                }
            }
            Store store = storeDao.findOne(order.getStoreId());
            if (store.getPayMode() == PayMode.CASHIER) {
                PaymentChannel channel = store.getChannel(scanCodeSignUpReq.isType());
                //校验开班信息
          /*  WorkShift workShift = workShiftDao.findByStoreIdAndClosed(order.getStoreId(), false);
            if (workShift == null) {
                return new ResponseEntity("无开班信息！请等待收银台开班！", HttpStatus.BAD_REQUEST);
            }*/
                Employee employee = employeeDao.findByUsernameAndEnabled(workShift.getOperatorId(), true).get(0);
                Map<String, String> map = new HashMap();
                map.put("url", getCashier(employee, channel));
                map.put("payMode", "CASHIER");
                return ResponseEntity.ok(map);
            } else {
                Map<String, String> map = new HashMap();
                StorePay storePay = storePayDao.findByStoreIdAndStartEnabled(order.getStoreId(), true);
                if (storePay == null) {
                    return ResponseEntity.badRequest().body("未配置支付方式，请联系客服");
                }
                if (StringUtils.isBlank(storePay.getMchId())) {
                    return ResponseEntity.badRequest().body("未配置支付方式，请联系客服");
                }
                ALLPayQrCodeResult result = new ALLPayQrCodeResult();
                //处理订单号
                String s = UuidUtil.getUuid();
                String appendStr = s.substring(s.length() - 4);

                if (StringUtils.isNotBlank(scanCodeSignUpReq.getMobile())) {
                    order.setCreatorName(scanCodeSignUpReq.getName());
                    order.setCreatorId(scanCodeSignUpReq.getMobile());
                    order.setMobileTag(workShift.getOperatorId());
                    List<Employee> employee = employeeDao.findByStoreIdAndUsername(order.getStoreId(), scanCodeSignUpReq.getMobile());
                    double orderComission = 0;
                    for (OrderItem item : order.getItems()) {
                        if (employee.size() > 0) {
                            Product product = productDao.findOne(item.getProductId());
                            double itemComission = new BigDecimal(order.addEmpCommissionBeforePay(product, item.getQuantity(), product.getCommissions(), employee.get(0), item)).multiply(new BigDecimal(store.getGlobalRate())).doubleValue();
                            item.setCommission(itemComission);
                            orderComission += itemComission;
                        }
                    }
                    order.setCommission(orderComission);
                }
                order.setPayOrderId(appendStr + order.getId());
                orderService.saveOrder(order);
                switch (storePay.getChannel()) {
                    case JL:
                        result = jlService.JLQRCode(order, storePay);
                        break;
                    case HUI_SHANG:
                        result = hsService.qrCodePay(scanCodeSignUpReq.getOrderId(), payType);
                        map.put("channel", "HUI_SHANG");
                        break;
                    case SAO_BEI:
                        result = saoBeiService.saoBeiQRCode(storePay, order);
                        map.put("channel", "SAO_BEI");
                    case HUI_FU:
                        result = huiFuService.huifuQRCode(storePay, order, payType);
                    case SUI_XIN_FU:
                        result = suiXinFuService.suixinfuOrderQRCode(storePay, order, payType);
                }
                if (result.isSuccess()) {
                    map.put("payMode", "THIRD_PARTY");
                    map.put("url", String.format("https://%s/v1/pay/jump/scan-code?orderId=%s", environment.getProperty("app.base.domain"), order.getId()));
                    redisService.set(order.getId() + "payUrl", result.getCodeImgURL(), 3*60*60);
                    return ResponseEntity.ok(map);
                } else {
                    return ResponseEntity.badRequest().body("获取支付二维码失败，请撤销按钮重新点单，如已付款，请耐心等待");
                }
            }
        });
    }

    /**
     * 获取非第三方支付二维码信息
     *
     * @return
     */
    private String getCashier(Employee employee, PaymentChannel channel) {
        String url = null;
        if (channel == PaymentChannel.ALIPAY_CASH) {
            url = employee.getAliPayUrl();
        }
        if (channel == PaymentChannel.WECHATPAY_CASH) {
            url = employee.getWechatPayUrl();
        }
        return url;
    }


    public void notifyScanCodeWs(Order order) {
        try {
            Map<String, String> map = new HashMap<>();
            map.put("orderId", order.getId());
            map.put("storeId", order.getStoreId());
            map.put("type", "SCAN");
            putWs(map);
        } catch (Exception e) {
            log.warn("Fail to send websocket notify to store:{}", order.getStoreId());
        }
    }

    private void putWs(Map<String, String> map) {
        try {
            //发送ws
            String url = urlUtils.getWs();
            OkHttpUtils.post(url, com.alibaba.fastjson.JSONObject.toJSONString(map));
        } catch (Exception ex) {
            log.error(" Invitation code initialization failed msg:{}", ex);
        }

    }

}
